home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / program / libkb100.zip / LIBKB-1.00 / SRC / _KBMSDOS.H < prev    next >
C/C++ Source or Header  |  1996-07-23  |  7KB  |  254 lines

  1. /* _kbmsdos.h -- low-level MSDOS keyboard installaton
  2.  * Copyright (C) 1995, 1996 Markus F.X.J. Oberhumer
  3.  * For conditions of distribution and use, see copyright notice in kb.h 
  4.  */
  5.  
  6.  
  7. /* WARNING: this file should *not* be used by applications. It is
  8.    part of the implementation of the keyboard library and is
  9.    subject to change. Applications should only use kb.h.
  10.  */
  11.  
  12.  
  13.  
  14. /***********************************************************************
  15. // keyboard handler 
  16. ************************************************************************/
  17.  
  18. #include "_handler.h"
  19.  
  20.  
  21. /***********************************************************************
  22. //
  23. ************************************************************************/
  24.  
  25. void kb_update(void)
  26. {
  27.     if (!_kb_mode)
  28.         return;
  29.     
  30.     /* Control-C check */
  31.     if (_kb_flags & KB_FLAG_SIGINT)
  32.     {
  33.         if (_kb_key[KB_SCAN_C] && 
  34.             (_kb_key[KB_SCAN_LCONTROL] || _kb_key[KB_SCAN_RCONTROL]))
  35.         {
  36. #if !defined(_KB_NO_SIGNALS)
  37.             raise(SIGINT);
  38. #else
  39.             kb_remove();
  40.             exit(EXIT_SIG(SIGINT));        /* sorry, but what else ? */
  41. #endif
  42.         }
  43.     }
  44.  
  45. #if !defined(_KB_NO_SIGNALS) && defined(SIGALRM)
  46.     if (_kb_flags & KB_FLAG_EMERGENCY_SIGALRM)
  47.         _kb_signal_alarm_update();
  48. #endif
  49. }
  50.  
  51.  
  52. /***********************************************************************
  53. //
  54. ************************************************************************/
  55.  
  56. #if defined(__BORLANDC__)
  57.  
  58. static void (interrupt far *_oldkeyint) (void) = NULL;
  59.  
  60. static int _kb_install(void)
  61. {
  62.     _oldkeyint = getvect(9);
  63.     setvect(9, _my_keyint);
  64.     return _my_keyint == getvect(9) ? 0 : -1;
  65. }
  66.  
  67. #pragma argsused
  68. static void _kb_remove(int final)
  69. {
  70.     if (_oldkeyint)
  71.         setvect(9, _oldkeyint);
  72. }
  73.  
  74. #endif /* __BORLANDC__ */
  75.  
  76.  
  77. /***********************************************************************
  78. //
  79. ************************************************************************/
  80.  
  81. #if defined(__WATCOMC__)
  82.  
  83. static void (__interrupt __far *_oldkeyint) () = NULL;
  84.  
  85. static int _kb_install(void)
  86. {
  87.     _oldkeyint = _dos_getvect(9);
  88.     _dos_setvect(9, _my_keyint);
  89.     return _my_keyint == _dos_getvect(9) ? 0 : -1;
  90. }
  91.  
  92. static void _kb_remove(int final)
  93. {
  94.     if (_oldkeyint)
  95.         _dos_setvect(9, _oldkeyint);
  96. }
  97.  
  98. #endif /* __WATCOMC__ */
  99.  
  100.  
  101. /***********************************************************************
  102. //
  103. ************************************************************************/
  104.  
  105. #if defined(__EMX__)
  106.  
  107. static int _kb_install(void)
  108. {
  109.     if (_osmode != DOS_MODE)
  110.         return -1;
  111.  
  112.     /* sorry, no interrupt handler possible with emx */
  113.     return -1;
  114. }
  115.  
  116. static void _kb_remove(int dummy)
  117. {
  118. }
  119.  
  120. #endif /* __EMX__ */
  121.  
  122.  
  123.  
  124. /***********************************************************************
  125. // djgpp
  126. //
  127. // note: Under DPMI the interrupt is always passed to the
  128. //       protected-mode handler first. But there have been reports about
  129. //       some strange situations under which a (faulty ?) DPMI host
  130. //       issued a real-mode interrupt. So we are paranoid and install
  131. //       a real-mode handler under DPMI as well. It shouldn't get called
  132. //       anyway, but it's there just in case.
  133. //       You can comment out the
  134. //       _go32_dpmi_set_protected_mode_interrupt_vector() call
  135. //       to verify that the real-mode handler is working fine.
  136. //
  137. //       The real-mode handler is needed for djgpp v1.
  138. ************************************************************************/
  139.  
  140. #if defined(__GO32__)
  141.  
  142. static unsigned long rm_count = 0;
  143.  
  144. static void _my_rm_keyint(_go32_dpmi_registers *regs)
  145. {
  146.     rm_count++;
  147.     _my_keyint(regs);
  148. }
  149.  
  150. /* See example code in djgpp2/info/libc.inf */
  151.  
  152. static _go32_dpmi_seginfo _key_pm_oldint;      /* original prot-mode key IRQ */
  153. static _go32_dpmi_seginfo _key_pm_int;    /* prot-mode interrupt segment info */
  154. static _go32_dpmi_seginfo _key_rm_oldint;      /* original real mode key IRQ */
  155. static _go32_dpmi_seginfo _key_rm_int;    /* real mode interrupt segment info */
  156. static _go32_dpmi_registers _key_rm_regs;
  157.  
  158.  
  159. static int _kb_install(void)
  160. {
  161. #if defined(__DJGPP__)
  162.     const int ino = _go32_info_block.master_interrupt_controller_base + 1;
  163. #else
  164.     const int ino = 9;
  165. #endif
  166.  
  167.     memset(&_key_pm_oldint, 0, sizeof(_key_pm_oldint));
  168.     memset(&_key_pm_int, 0, sizeof(_key_pm_int));
  169.     memset(&_key_rm_oldint, 0, sizeof(_key_rm_oldint));
  170.     memset(&_key_rm_int, 0, sizeof(_key_rm_int));
  171.     memset(&_key_rm_regs, 0, sizeof(_key_rm_regs));
  172.  
  173.     /* get and allocate pm handler */
  174.     _go32_dpmi_get_protected_mode_interrupt_vector(ino, &_key_pm_oldint);
  175.     _key_pm_int.pm_selector = _go32_my_cs();
  176.     _key_pm_int.pm_offset = (unsigned long) _my_keyint;
  177.     if (_go32_dpmi_allocate_iret_wrapper(&_key_pm_int) != 0)
  178.         goto error;
  179.  
  180.     /* get and allocate rm handler */
  181.     if (!(_kb_flags & KB_FLAG_DJGPP_NO_RM))
  182.     {
  183.         _go32_dpmi_get_real_mode_interrupt_vector(ino, &_key_rm_oldint);
  184.         _key_rm_int.pm_selector = _go32_my_cs();
  185.         _key_rm_int.pm_offset = (unsigned long) _my_rm_keyint;
  186.         if (_go32_dpmi_allocate_real_mode_callback_iret(&_key_rm_int, &_key_rm_regs) != 0)
  187.             goto error;
  188.     }
  189.  
  190.     /* set pm handler */
  191.     if (_go32_dpmi_set_protected_mode_interrupt_vector(ino, &_key_pm_int) != 0)
  192.         goto error;
  193.  
  194.     /* set rm handler */
  195.     if (!(_kb_flags & KB_FLAG_DJGPP_NO_RM))
  196.         _go32_dpmi_set_real_mode_interrupt_vector(ino, &_key_rm_int);
  197.  
  198.     return 0;
  199.  
  200.  
  201. error:
  202.     memset(&_key_pm_oldint, 0, sizeof(_key_pm_oldint));
  203.     memset(&_key_pm_int, 0, sizeof(_key_pm_int));
  204.     memset(&_key_rm_oldint, 0, sizeof(_key_rm_oldint));
  205.     memset(&_key_rm_int, 0, sizeof(_key_rm_int));
  206.     memset(&_key_rm_regs, 0, sizeof(_key_rm_regs));
  207.  
  208.     return -1;
  209. }
  210.  
  211.  
  212. static void _kb_remove(int final)
  213. {
  214. #if defined(__DJGPP__)
  215.     const int ino = _go32_info_block.master_interrupt_controller_base + 1;
  216. #else
  217.     const int ino = 9;
  218. #endif
  219.     int r = 0;
  220.  
  221.     if (_key_pm_oldint.pm_selector != 0 || _key_pm_oldint.pm_offset != 0)
  222.         r |= _go32_dpmi_set_protected_mode_interrupt_vector(ino, &_key_pm_oldint);
  223.     if (_key_rm_oldint.rm_segment != 0 || _key_rm_oldint.rm_offset != 0)
  224.         r |= _go32_dpmi_set_real_mode_interrupt_vector(ino, &_key_rm_oldint);
  225.  
  226.     if (final && r == 0)
  227.     {
  228.         if (_key_pm_int.pm_selector != 0 || _key_pm_int.pm_offset != 0)
  229.             _go32_dpmi_free_iret_wrapper(&_key_pm_int);
  230.         if (_key_rm_int.size)
  231.             _go32_dpmi_free_real_mode_callback(&_key_rm_int);
  232.  
  233. #if defined(KB_DEBUG) && (KB_DEBUG >= 2)
  234.         if (rm_count)
  235.             fprintf(stderr,"_kb_remove: info: %lu real-mode interrupts\n",
  236.                 rm_count);
  237. #endif
  238.  
  239.         memset(&_key_pm_oldint, 0, sizeof(_key_pm_oldint));
  240.         memset(&_key_pm_int, 0, sizeof(_key_pm_int));
  241.         memset(&_key_rm_oldint, 0, sizeof(_key_rm_oldint));
  242.         memset(&_key_rm_int, 0, sizeof(_key_rm_int));
  243.     }
  244. }
  245.  
  246. #endif /* __GO32__ */
  247.  
  248.  
  249.  
  250. /*
  251. vi:ts=4
  252. */
  253.  
  254.